package com.jnshu.config;

import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.jnshu.exception.MyException;
import com.jnshu.tools.JwtUtil;
import com.jnshu.tools.binding.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.Map;

/**负载均衡微信登录拦截器*/
@Slf4j
@Component
public class WeChatInterceptor implements HandlerInterceptor {

    /** preHandle方法是进行处理器拦截用的，顾名思义，该方法将在Controller处理之前进行调用，
     * SpringMVC中的Interceptor拦截器是链式的，可以同时存在*/
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("WeChatInterceptor拦截器被调用=====================================");
        //判断请求中是否带有token令牌，同时对token令牌进行验证
        String token = request.getHeader("token");
        log.info("WeChatInterceptor从request.getHeader请求头中获取的token是："+token);
        //判断token令牌中是否存有数据
        if ("".equals(token) || token==null){
            log.error("WeChatInterceptor从request.getHeader请求头中获取的token不存在，返回错误");
            throw new MyException(500,"用户不存在，请重新授权登录");
        }
        //将token使用jwt解析
        DecodedJWT jwt = JwtUtil.verifyToken(token);
        log.info("WeChatInterceptor中解析后的token为："+jwt);
        Map<String, Claim> claims = jwt.getClaims();
        log.info("WeChatInterceptor里解析后的token的有效载体信息为："+ JsonUtil.toJsonString(claims));
        String id = claims.get("id").asString();
        log.info("WeChatInterceptor从token中获取的id为："+id);
        Date date =jwt.getExpiresAt();
        long time = date.getTime();
        //判断token是否过期
        if (time > System.currentTimeMillis()){
            request.setAttribute("id",id);
            return true;
        }else {
            throw new MyException(500,"登录已过期，请重新授权登录");
        }
    }

    /**postHandle:进入Handle方法之后，返回ModelAndView之前执行；
     * 使用场景从ModelAndView参数出发例如将共用的模型数据在这里传入到视图，也可以统一制定显示的视图等*/
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    /**afterHandler:在执行handler完成后执行此方法，使用统一的异常处理，统一的日志处理等；
     * 该方法在整个请求完成之后执行，主要作用是用于清理资源*/
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}
